{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Capsule Networks\n",
    "\n",
    "### Demo  - We'll run the Tensorflow code for CapsNet (the new state-of-the-art performance on MNIST, more than convolutional networks)\n",
    "\n",
    "## What is the current State of the Art in Image Classification & Object Recognition?\n",
    "\n",
    "- Image classification is a central problem in machine learning\n",
    "- we would not have been successful if we simply used a raw multi-layer perceptron connected to each pixel of an image. \n",
    "- On top of becoming quickly intractable, this direct operation is not very efficient as pixels are spatially correlated.\n",
    " ---So we initially need to extract features that are:\n",
    " ---meaningful and\n",
    " ---low-dimensional\n",
    "- And that's where convolutional neural networks come in the game!\n",
    "- Convolutional Networks are the state of the art algorithm\n",
    "- Basic idea is show an algorithm labeled images i.e  photos of dogs labeled \"dog\" eventually it will start to abstract features that are more likely to indicate the presence of an actual dog\n",
    "- We can use this model to classify new, unlabeled images. \n",
    "\n",
    "![alt text](https://www.mathworks.com/content/mathworks/www/en/discovery/convolutional-neural-network/jcr:content/mainParsys/image_copy.adapt.full.high.jpg/1508999490138.jpg \"Logo Title Text 1\")\n",
    "- First, an input image is fed to the network. \n",
    "- Filters of a given size scan the image and perform convolutions. \n",
    "- The obtained features then go through an activation function. Then, the output goes through a succession of pooling and other convolution operations.\n",
    "- features are reduced in dimension as the network goes on.\n",
    "- At the end, high-level features are flattened and fed to fully connected layers, which will eventually yield class probabilities through a softmax layer.\n",
    "- During training time, the network learns how to recognize the features that make a sample belong to a given class through backpropagation.\n",
    "\n",
    "ConvNets appear as a way to construct features that we would have had to handcraft ourselves otherwise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout, Activation, Flatten\n",
    "from keras.layers import Convolution2D, MaxPooling2D\n",
    "from keras.utils import np_utils\n",
    "from keras.datasets import mnist\n",
    " \n",
    "# 4. Load pre-shuffled MNIST data into train and test sets\n",
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    " \n",
    "# 7. Define model architecture\n",
    "model = Sequential()\n",
    " \n",
    "model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(1,28,28)))\n",
    "model.add(Convolution2D(32, 3, 3, activation='relu'))\n",
    "model.add(MaxPooling2D(pool_size=(2,2)))\n",
    "model.add(Dropout(0.25))\n",
    " \n",
    "model.add(Flatten())\n",
    "model.add(Dense(128, activation='relu'))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Dense(10, activation='softmax'))\n",
    " \n",
    "# 8. Compile model\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    " \n",
    "# 9. Fit model on training data\n",
    "model.fit(X_train, Y_train, \n",
    "          batch_size=32, nb_epoch=10, verbose=1)\n",
    " \n",
    "# 10. Evaluate model on test data\n",
    "score = model.evaluate(X_test, Y_test, verbose=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![alt text](https://cdn-images-1.medium.com/max/2000/1*xAd4dHFESXxGm40IdsHP1Q.png \"Logo Title Text 1\")\n",
    "\n",
    "## Improvements to CNNs\n",
    "\n",
    "### AlexNet \n",
    "![alt text](https://stanford.edu/~shervine/images/AlexNet.png \"Logo Title Text 1\")\n",
    "1. Krizhevsky introduced better non-linearity in the network with the ReLU activation, whose derivative is 0 if the feature is below 0 and 1 for positive values. This proved to be efficient for gradient propagation.\n",
    "2. introduced the concept of dropout as regularization. From a representation point of view, you force the network to forget things at random, so that it can see your next input data from a better perspective.\n",
    "3. Introduced data augmentation. When fed to the network, images are shown with random translation, rotation, crop. That way, it forces the network to be more aware of the attributes of the images, rather than the images themselves.\n",
    "4. Deeper. They stacked more convolutional layers before pooling operations. The representation captures consequently finer features that reveal to be useful for classification.\n",
    "\n",
    "This network largely outperformed what was state-of-the-art back in 2012, with a 15.4% top-5 error on the ImageNet dataset.\n",
    "\n",
    "### VGGNet \n",
    "\n",
    "![alt text](https://stanford.edu/~shervine/images/VGGNet.png \"Logo Title Text 1\")\n",
    "\n",
    "1. Went Deeper\n",
    "\n",
    "### GoogleNet\n",
    "\n",
    "![alt text](https://stanford.edu/~shervine/images/GoogLeNet.png \"Logo Title Text 1\")\n",
    "\n",
    "1.  convolutions with different filter sizes are processed on the same input, and then concatenated together.\n",
    "2. This allows the model to take advantage of multi-level feature extraction at each step. For example, general features can be extracted by the 5x5 filters at the same time that more local features are captured by the 3x3 convolutions.\n",
    "\n",
    "### ResNEt\n",
    "\n",
    "![alt text](https://stanford.edu/~shervine/images/ResNet.png \"Logo Title Text 1\")\n",
    "\n",
    "1. at some point, we realize that stacking more layers does not lead to better performance. In fact, the exact opposite occurs. But why is that? The Gradient. \n",
    "2. every two layers, there is an identity mapping via an element-wise addition. This proved to be very helpful for gradient propagation, as the error can be backpropagated through multiple paths.\n",
    "3. This helps to combine different levels of features at each step of the network, just like we saw it with the inception modules.\n",
    "\n",
    "### DenseNet\n",
    "\n",
    "![alt text](https://stanford.edu/~shervine/images/DenseNet.png \"Logo Title Text 1\")\n",
    "1. proposes entire blocks of layers connected to one another.\n",
    "\n",
    "### Patterns \n",
    "\n",
    "1. Networks are designed to be deeper and deeper.\n",
    "\n",
    "2. Computational tricks (ReLU, dropout, batch normalization) have been also introduced alongside them and had a significant impact in improving performance.\n",
    "\n",
    "3. Increasing use of connections between the layers of the network, which helps for producing diverse features and revealed to be useful for gradient propagation.\n",
    "\n",
    "## The Problem with Convolutional Networks\n",
    "\n",
    "\n",
    "![alt text](https://i.imgur.com/8XWFA7o.png \"Logo Title Text 1\")\n",
    "\n",
    "- max-pooling throws away information about the precise position of the entity within the region.\n",
    "\n",
    "![alt text](https://i.imgur.com/qTJN6CP.png \"Logo Title Text 1\")\n",
    "\n",
    "![alt text](https://i.imgur.com/eedQQo3.png \"Logo Title Text 1\")\n",
    "\n",
    "![alt text](https://i.imgur.com/XTrIAQK.png \"Logo Title Text 1\")\n",
    "\n",
    "- CNNs have trouble generalizing to novel viewpoints. \n",
    "- The ability to deal with translation is built in, but for the other dimensions of an affine transformation we have to chose between replicating feature detectors on a grid that grows exponentially with the number of dimensions, or increasing the size of the labeled training set in a similarly exponential way. \n",
    "\n",
    "Oh! And don't forget this 6 day old paper on fooling ConvNets by modifying just a few pixels\n",
    "\n",
    "https://arxiv.org/abs/1710.08864\n",
    "\n",
    "## The Capsule Network\n",
    "\n",
    "![alt text](https://pic2.zhimg.com/v2-55375292bced12de999d654c76118c75_r.png \"Logo Title Text 1\")\n",
    "\n",
    "- CNNs cannot handle rotation at all - if they are trained on objects in one orientation, they will have trouble when the orientation is changed.  \n",
    "- Pooling gives some translational invariance in much deeper layers, but only in a crude way.\n",
    "- The human brain must achieve translational invariance in a much better way\n",
    "- Hinton posits that the brain has modules he calls “capsules” which are particularly good at handling different types of visual stimulus and encoding things like pose – for instance, there might be one for cars and another for faces. - - The brain must have a mechanism for “routing” low level visual information to what it believes is the best capsule for handling it. \n",
    "- According to Hinton, CNNs do routing by pooling. Pooling was introduced to reduce redundancy of representation and reduce the number of parameters, recognizing that precise location is not important for object detection. \n",
    "- But Pooling does routing in a very crude way - for instance max pooling just pics the neuron with the highest activation, not the one that is mostlikely relevant to the task at hand.\n",
    "\n",
    "\n",
    "### What is it? \n",
    "- The capsule is a neural network architecture where a typical layer is modified to contain sub-structures. \n",
    "- The typical layer of units becomes a layer of capsules. I\n",
    "- Instead of making a neural network \"deeper\" in height, it makes it deeper in nesting or inner structure. That's all it is, basically.\n",
    "- The model is robust to affine transformations\n",
    "\n",
    "### 2 Key Features\n",
    "\n",
    "#### Layer-based squashing & dynamic routing. \n",
    "\n",
    "- In a typical neural network, only the output of a unit is squashed (by a non-linear activation function). \n",
    "- In a capsule network, a capsule is squashed as a whole vector. It does make the \"unit\" bigger in the neural net.\n",
    "- Is it more biologically plausible than traditional network? I would say, \"slightly\". The new one relies less on backpropagation, and might work by associative learning between capsules.\n",
    "- So its replacing the scalar-output feature detectors of CNNs with vector-output capsules and max-pooling with routing-by-agreement \n",
    "- To replicate learned knowledge across space they made all but the last layer of capsules be convolutional\n",
    "\n",
    "###  More\n",
    "\n",
    "- For low level capsules, location information is “place-coded” by which capsule is active. \n",
    "- As we ascend the hierarchy more and more of the positional information is “rate-coded” in the real-valued components of the output vector of a capsule. \n",
    "- This shift from place-coding to rate-coding combined with the fact that higher-level capsules represent more complex entities with more degrees of freedom suggests that the dimensionality of capsules should increase as we ascend the hierarchy.\n",
    "- There many possible ways to implement the general idea of capsules\n",
    "\n",
    "### The cost of this new architecture? \n",
    "\n",
    "![alt text](https://pic2.zhimg.com/v2-508e88f258c1be4a4d64bae1c5ad1685_b.jpg \"Logo Title Text 1\")\n",
    "\n",
    "- The forward pass has an extra outer loop. \n",
    "- It takes r iterations over all units (instead of 1) to compute the output. \n",
    "- The data flow is more complicated\n",
    "- That makes it harder to calculate gradients, and the model may suffer more from vanishing gradients. \n",
    "- This could prevent the network from scaling and becoming a deep learning rock star.\n",
    "- The NIPS paper did not provide stability analysis for the forward pass. We don't know the asymptotic behavior of the layers after r iterations. No idea how stable it will be for attacking difficult learning problems.\n",
    "\n",
    "### Lets look at some code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
